#ifndef _APICAMION_H_
#define _APICAMION_H_

#include <stdio.h>
#include <stdlib.h>
#include "../common.h"
#include <sys/types.h>
// Bibliotecas IPC
#include <sys/types.h>
#include <unistd.h>
// Clases propias
#include "../IPC/Semaphore/Semaphore.h"
#include "../IPC/SharedMemory/ControlDataSharedMemory.h"
#include "../IPC/MessageQueue/TruckDoorInputMessageQueue.h"
#include "../IPC/MessageQueue/TruckDoorOutputMessageQueue.h"
#include "../IPC/MessageQueue/TruckInputMessageQueue.h"
#include "../IPC/MessageQueue/TruckOutputMessageQueue.h"
#include "../IPC/MessageQueue/ChargeToTruckMessageQueue.h"


class APICamion {

private:
	Semaphore semTruckDoor;
	Semaphore semTruck;
	Semaphore semControl;
	ControlDataSharedMemory shMem;

	// Comunicación que involucra la carga de personas
	TruckInputMessageQueue truckChargeInputQueue;
	TruckOutputMessageQueue truckChargeOutputQueue;
	
	// Comunicación que involucra la descarga de personas
	TruckInputMessageQueue truckDischargeInputQueue;
	TruckOutputMessageQueue truckDischargeOutputQueue;
	
	// Cola donde la API va dejando a las personas para que luego el camión
	// las vaya subiendo
	ChargeToTruckMessageQueue chargeToTruckQueue;
	
	// Buffer para escribir mensajes tanto para enviar, como para mostrar
	// por pantalla
	char buffer[255];

public:

	//
	APICamion();

	//
	virtual ~APICamion();
	
	/* Un camión llega a la sala para cargar personas. En el caso de que otro
	 * camión esté cargando personas, el mismo se bloquea. Luego, cuando un
	 * camión se va, este lo despierta para que el mismo proceda a cargar gente.
	 */
	void ingresarEnSala(int nroCamion, int *error);
	
	//
	void abandonarSala(int nroCamion, int *error);
	
	/* El camión ingresa a la memoria compartida */
	long subirPersona(int nroCamion, bool *salaLiberada, int *error);
	
	// 
	void bajarPersona(int nroCamion, long idPersona, int *error);
	
private:
	
	// 
	void desbloquearPuertas(int nroCamion, bool array[], int *error);
	
	//
	long obtenerIdPersonaASubir(int nroCamion, int *error);
	
	// 
	void handshakeConPersonaASubirACamion(int nroCamion, long idPersona, int *error);
	
	// 
	void accederAMemoriaCompartida(int id, int *error);
	
	// 
	void liberarMemoriaCompartida(int id, int *error);
	
	//
	void liberarSala(int nroCamion, ControlData *data, int *error);
};

#endif


	
	 
  
